#!/bin/bash

# Default parameter values
HOST="127.0.0.1"
PORT="10200"
USER="admintest@tenant1"
PASSWORD="admin"
DATABASE=""
TMPDIR="./tmp"
VARDIR="./var"
LOGDIR="./var/log"
TIMER_FILE="$LOGDIR/timer"
#MYSQLTEST_BIN="/u01/obclient/bin/mysqltest"
MYSQLTEST_BIN="/home/gisdev/develop/hycli/client/mysqltest"
TEST_DIR="./mysql_test/t"
TEST_FILE_SUFFIX=".test"
RESULT_DIR=""
RESULT_FILE_SUFFIX=".result"
RECORD=0
RECORD_DIR=""
RECORD_FILE_SUFFIX=".record"
TEST_SET=""
SUITE=""
SUITE_DIR="./mysql_test/test_suite"
ALL=0
TAIL_LINES="20"
MODE="mysql"


# --mode=MODE
# --component=COMPONENT
# --test-server=TEST_SERVER
# --obclient-bin=OBCLIENT_BIN
# --exclude=EXCLUDE

# --test-pattern=TEST_PATTERN
# --init-sql-dir=INIT_SQL_DIR
# --init-sql-files=INIT_SQL_FILES
# --need-init
# --init-only
# --auto-retry
# --psmall
# --special-run 
# --sp-hint=SP_HINT 
# --sort-result
# --slices=SLICES 
# --slice-idx=SLICE_IDX
# --slb-host=SLB_HOST
# --exec-id=EXEC_ID 
# --case-filter=CASE_FILTER
# --psmall-test=PSMALL_TEST
# --psmall-source=PSMALL_SOURCE
# --ps
# --test-tags=TEST_TAGS
# --tags=TAGS 
# --regress-suite-map=REGRESS_SUITE_MAP
# --regress_suite=REGRESS_SUITE
# --reboot-cases=REBOOT_CASES
# --reboot-timeout=REBOOT_TIMEOUT
# --reboot-retries=REBOOT_RETRIES
# --collect-all 
# --collect-components=COLLECT_COMPONENTS
# --case-timeout=CASE_TIMEOUT
# --log-pattern=LOG_PATTERN
# --cluster-mode=CLUSTER_MODE
# --disable-reboot  
# --fast-reboot 
# -h, --help  
# -v, --verbose  



TEST_FILE=""
RESULT_FILE=""
NAMEMAXLEN=0

declare -a test_files
declare -a result_files
declare -a record_files
declare -a extra_args



# Function to display error message and exit
error_exit() {
    echo "$1" >&2
    exit 1
}

# Function to check if directories and files exist, otherwise exit
check_directories_and_files() {
    echo "check directories..."

	
    if [ "$RECORD" -eq 1 ] && [ -n "$RECORD_DIR" ]; then
    	if [ ! -d "$RECORD_DIR" ]; then
        	error_exit "RECORD directory \"$RECORD_DIR\" does not exist."        	
    	fi
    fi


    for item in MYSQLTEST_BIN TMPDIR VARDIR LOGDIR; do
        # Get the variable value
        value=$(eval echo \$$item)
        # Get the variable name
        var_name=$item
        if [ ! -e "$value" ]; then
            error_exit "File or directory $var_name: \"$value\" does not exist."
        fi
    done
}


set_test_and_result_files() {
    echo "set_test_and_result_files...$TEST_SET...$SUITE...$ALL"
    # Check if TEST_SET is set
    if [ -n "$TEST_SET" ]; then
        echo "000-Checking TEST_SET..."
        handle_case
    elif [ -n "$SUITE" ]; then
        echo "000-Checking SUIT..."
        handle_suites
    elif [ "$ALL" -eq 1 ]; then
        echo "000-Checking ALL suites..."
        handle_all_suites
    fi
}


# Function to set TEST_FILE and RESULT_FILE based on TEST_SET and RESULT_DIR
handle_case() {

    # Check if TEST_SET is set
    if [ -n "$TEST_SET" ]; then
        echo "Checking TEST_SET..."

        # Check if TEST_DIR directory exists
        if [ ! -d "$TEST_DIR" ]; then
            error_exit "Directory '$TEST_DIR' does not exist."
        fi
        
        # Set TEST_FILE
        local test_file="$TEST_DIR/$TEST_SET$TEST_FILE_SUFFIX"
        echo "TEST_FILE: $test_file"

        # Check if RESULT_DIR directory exists        
        if [ ! -d "$RESULT_DIR" ]; then
            error_exit "Directory '$RESULT_DIR' does not exist."
        fi            

        # Set RESULT_FILE
        local result_file="$RESULT_DIR/mysql/$TEST_SET$RESULT_FILE_SUFFIX"
        echo "RESULT_FILE: $result_file"

        # Append TEST_FILE and RESULT_FILE to the respective arrays
        test_files+=("$test_file")
        result_files+=("$result_file")

	    if [ "$RECORD" -eq 1 ]; then
        	record_file="${RECORD_DIR}/mysql/$TEST_SET$RECORD_FILE_SUFFIX"
		    echo "RECORD_FILE: $record_file"
        	record_files+=("$record_file")
            echo "@@record_file: $record_file"
    	fi
    fi
}


handle_suites() {
    local suites="$SUITE"
    echo "suites: $suites"
    IFS=',' read -ra suite_list <<< "$suites"  # 以逗号分隔字符串为数组
    if [ "${#suite_list[@]}" -eq 1 ]; then
        handle_suite "$suites"  # 如果只有一个参数，直接处理该参数
    else
        for suite_name in "${suite_list[@]}"; do
            handle_suite "$suite_name"
        done
    fi
}


handle_suite() {
	
    local suitename="$1"

    # If SUITE is provided as a parameter, update suitename
    # if [ -n "$SUITE" ]; then
    #     suitename="$SUITE"
    # fi

    # Check if suitename is set
    if [ -z "$suitename" ]; then
        error_exit "SUITE is not set."
    fi

    echo "SUITE: $suitename" 
    
    local suite_dir="$SUITE_DIR/$suitename"
    
    # Check if SUITE_DIR exists
    if [ ! -d "$suite_dir" ]; then
        error_exit "Suite directory '$suite_dir' does not exist."
    fi
    
    # Find all test files in $SUITE_DIR/SUITE/t with the suffix TEST_FILE_SUFFIX
    current_test_files=($(find "$suite_dir/t" -maxdepth 1 -type f -name "*$TEST_FILE_SUFFIX"))
    
    # Find all result files in $SUITE_DIR/SUITE/r/mysql with the suffix RESULT_FILE_SUFFIX
    # result_files=($(find "$suite_dir/r/mysql" -maxdepth 1 -type f -name "*$RESULT_FILE_SUFFIX"))
    for test_file in "${current_test_files[@]}"; do
        echo "@@test_file: $test_file"
        # result_file="${test_file/t\//r\/mysql\/}"  # Replace t/ with r/mysql/
        # result_file="${result_file%$TEST_FILE_SUFFIX}$RESULT_FILE_SUFFIX"  # Replace suffix

	    test_files+=("$test_file")
	    result_file="$(echo "$test_file" | sed 's@/t/@/r/mysql/@; s/\.test$/.result/')"
        result_files+=("$result_file")
        echo "@@result_file: $result_file"

	    if [ "$RECORD" -eq 1 ]; then
            # Extract casename from result_file path
            casename=$(basename "${result_file%$RESULT_FILE_SUFFIX}")
            casename="${casename%.*}"  # Remove extension

            # Generate record file path
            record_file="${RECORD_DIR}/${suitename}/${casename}${RECORD_FILE_SUFFIX}"
            record_files+=("$record_file")
            echo "@@record_file: $record_file"
        fi

    done
    
    # Check if the number of test files matches the number of result files
    # if [ "${#test_files[@]}" -ne "${#result_files[@]}" ]; then
    #     error_exit "Number of test files does not match number of result files."
    # fi   
}



handle_all_suites() {
    # Check if ALL is set
    if [ "$ALL" -eq 1 ]; then
        echo "Handling ALL suites..."
        # Check if SUITE_DIR directory exists
        if [ ! -d "$SUITE_DIR" ]; then
            error_exit "Directory '$SUITE_DIR' does not exist."
        fi

        # Iterate over all subdirectories in SUITE_DIR
        for suite_dir in "$SUITE_DIR"/*/; do
            # Extract the suite name from the directory path
            suite_name=$(basename "$suite_dir")
            echo "Handling suite: $suite_name"
            # Call handle_suite function for each suite
            handle_suite "$suite_name"
        done
    fi
}


# Function to execute mysqltest with each pair of test and result files
execute_mysqltest_with_files() {
    local test_results=()
    local total_cases=0
    local passed_cases=0
    local failed_cases=0
    local error_encountered=0  # Track if any error encountered

    echo "*******execute_mysqltest_with_files array: ${test_files[@]}****"

    echo "testfilesL:${#test_files[@]};"

    # Loop through each pair of test and result files
    for ((i = 0; i < ${#test_files[@]}; i++)); do
        test_file="${test_files[$i]}"
        #result_file="${result_files[$i]}"

        #test_file="${test_files[$i]}"
        #test_dir=$(dirname "$test_file")  # 提取测试文件所在目录
        #test_filename=$(basename "$test_file")  # 提取测试文件名
        #test_case="${test_filename%$TEST_FILE_SUFFIX}"  # 提取测试用例名
        #result_dir="${test_dir/t\//r\/mysql\/}"  # 构建结果文件所在目录
        #result_file="${result_dir}/${test_case}$RESULT_FILE_SUFFIX"  # 构建结果文件路径

	    test_filename=$(basename "$test_file")  # 提取文件名
        echo "&&&MODE---$MODE"
        # 根据 MODE 判断是否继续执行
        if [[ "$MODE" == "mysql" && "$test_filename" == *.mysql.test ]]; then
            # 继续执行 MySQL 相关操作
            echo "Processing MySQL test file: $test_filename"
        elif [[ "$MODE" == "oracle" && "$test_filename" == *.ora.test ]]; then
            # 继续执行 Oracle 相关操作
            echo "Processing Oracle test file: $test_filename"
        else
            # 跳过后续操作
            echo "Skipping file: $test_filename"
            continue
        fi

        len=${#test_filename}
        if [ "$len" -gt "$NAMEMAXLEN" ]; then
            NAMEMAXLEN=$len
        fi
        echo "execute result_file0: $test_filename"
    	result_file="${test_file/t\//r\/mysql\/}"  # 构建对应的 result_file 路径
        echo "execute result_file1: $result_file"
    	result_file="${result_file%$TEST_FILE_SUFFIX}$RESULT_FILE_SUFFIX"  # 替换后缀
        echo "execute result_file2: $result_file"

	    result_file="$(echo "$test_file" | sed 's@/t/@/r/mysql/@; s/\.test$/.result/')"
    
    	# 检查 result_file 是否存在于 result_files 中
    	if ! [[ " ${result_files[@]} " =~ " ${result_file} " ]]; then
            result_file=""  # 如果不存在，则将 result_file 设为空字符串
    	fi

        echo "execute result_file3: $result_file"
        
        # Set TEST_FILE and RESULT_FILE to the current pair of files
        TEST_FILE="$test_file"
        RESULT_FILE="$result_file"

	  # Determine if record mode is enabled
        record_option=""
        if [ "$RECORD" -eq 1 ]; then
            record_option="--record"
        fi
        

	    echo "\"$MYSQLTEST_BIN\" --host=\"$HOST\" --port=\"$PORT\" --tmpdir=\"$TMPDIR\" --logdir=\"$LOGDIR\" --user=\"$USER\" --password=\"$PASSWORD\" --database=\"$DATABASE\" --timer-file=\"$TIMER_FILE\" --test-file=\"$TEST_FILE\" --result-file=\"$RESULT_FILE\"  \"${extra_args[@]}\""


        # Execute mysqltest with the current pair of files and capture output
        start_time=$(date +%s.%N)

        output="$("$MYSQLTEST_BIN" --host="$HOST" --port="$PORT" --tmpdir="$TMPDIR" --logdir="$LOGDIR" --user="$USER" --password="$PASSWORD" --database="$DATABASE" --timer-file="$TIMER_FILE" --test-file="$TEST_FILE" --result-file="$RESULT_FILE"   "${extra_args[@]}" 2>&1 || true)"

        # exit_code=$?  # Get the exit code of the command
        end_time=$(date +%s.%N)
        execution_time=$(echo "scale=2; ($end_time - $start_time) / 1" | bc)

        # Parse test case name from test file path
        test_case=$(basename "$test_file" "$TEST_FILE_SUFFIX")


        echo "execute output: $output"


        # Determine status based on exit code
        # if [ $exit_code -eq 0 ]; then
        if [[ $output == "ok" ]]; then
        #if grep -q "\<ok\>" <<< "$output"; then
            status="PASSED"
            ((passed_cases++))
        else
            status="FAILED"
            ((failed_cases++))
            error_encountered=1  # Set error flag
        fi

        # Add test result to array
        test_results+=("$test_case" "$execution_time" "$status")

        ((total_cases++))

	    #if [ "$RECORD" -eq 1 ]; then
        #	for logfile in "$LOGDIR"/*.log; do
         #   	if [ -f "$logfile" ]; then
         #       		recordfile="${logfile%.log}$RECORD_FILE_SUFFIX"
         #       		cp "$logfile" "$recordfile"
         #   	fi
        #	done
    	   #fi

    done

    # Output results summary
    #echo "+----------+--------------+-----------+"
    #echo "| Result (Total $total_cases, Passed $passed_cases, Failed $failed_cases) |"
    #echo "+----------+--------------+-----------+"
    #echo "| Case     |     Cost (s) | Status    |"
    #echo "+----------+--------------+-----------+"

    content="Result (Total $total_cases, Passed $passed_cases, Failed $failed_cases)"
    padding=$((NAMEMAXLEN - 2 - ${#content} + 14 + 11 + 2))  # 减去两边的 | 和内容长度

    echo "+$(printf '%-*s' "$NAMEMAXLEN" "" | tr ' ' '-')+--------------+-----------+"
    #echo "| Result (Total $total_cases, Passed $passed_cases, Failed $failed_cases) |"
    printf "| %s%*s |\n" "$content" "$padding" ""
    echo "+$(printf '%-*s' "$NAMEMAXLEN" "" | tr ' ' '-')+--------------+-----------+"
    echo "| Case$(printf '%*s' "$((NAMEMAXLEN - 6))" "") | Cost (s)     | Status    |"
    echo "+$(printf '%-*s' "$NAMEMAXLEN" "" | tr ' ' '-')+--------------+-----------+"
    
    valuelen=$((NAMEMAXLEN - 2))
    # Output detailed results
    for ((j = 0; j < ${#test_results[@]}; j+=3)); do
        #printf "| %-9s| %12s | %-8s|\n" "${test_results[$j]}" "${test_results[$j+1]}" "${test_results[$j+2]}"
        printf "| %-${valuelen}s | %-12s | %-9s |\n" "${test_results[$j]}" "${test_results[$j+1]}" "${test_results[$j+2]}"
    done
    #echo "+----------+--------------+-----------+"
    echo "+$(printf '%-*s' "$NAMEMAXLEN" "" | tr ' ' '-')+--------------+-----------+"

    # Return error flag
    return $error_encountered
}





# Function to display usage information
usage() {
    echo "Usage: $0 [--host <hostname>] [--port <port>] [--tmpdir <tmpdir>] [--logdir <logdir>] [--user <username>] [--password <password>] [--database <database>] [--timer-file <timerfile>] [--test-file <testfile>] [--result-file <resultfile>]" 1>&2
    exit 1
}


# Parse command line options
while [[ $# -gt 0 ]]; do
    case "$1" in
        --host)
            HOST="$2"
	      echo "HOST: $HOST"
            shift 2
            ;;
        --port)
            PORT="$2"
	      echo "PORT: $PORT"
            shift 2
            ;;        
        --user)
            USER="$2"
	      echo "USER: $USER"
            shift 2
            ;;
        --password)
            PASSWORD="$2"
	      echo "PASSWORD: $PASSWORD"
            shift 2
            ;;
        --database)
            DATABASE="$2"
	      echo "DATABASE: $DATABASE"
            shift 2
            ;;
	  --tmpdir)
            TMPDIR="$2"
	      echo "TMPDIR: $TMPDIR"
            shift 2
            ;;
        --logdir)
            LOGDIR="$2"
	      echo "LOGDIR: $LOGDIR"
            shift 2
            ;;
        --timer-file)
            TIMER_FILE="$2"
	      echo "TIMER_FILE: $TIMER_FILE"
            shift 2
            ;;

	  --mysqltest-bin)
            MYSQLTEST_BIN="$2"
	      echo "MYSQLTEST_BIN: $MYSQLTEST_BIN"
            shift 2
            ;;
	  --test-dir)
            TEST_DIR="$2"
	      echo "TEST_DIR: $TEST_DIR"		
            shift 2
            ;;
	  --result-dir)
            RESULT_DIR="$2"
	      echo "RESULT_DIR: $RESULT_DIR"
            shift 2
            ;;	 

	  --test-set)
            TEST_SET="$2"
	      echo "TEST_SET: $TEST_SET"
            shift 2
            ;;
	  --suite)
            SUITE="$2"
	      echo "SUITE: $SUITE"
            shift 2
            ;;
	  --suite-dir)
            SUITE_DIR="$2"	
	      echo "SUITE_DIR: $SUITE_DIR"       
            shift 2
            ;;
      --mode)
            MODE="$2"	
	      echo "MODE: $MODE"       
            shift 2
            ;;
      --mode=*)
            MODE="${1#--mode=}"
            echo "MODE: $MODE"
            shift
            ;;
	  --all)
            ALL=1
	      echo "ALL: 1"
            shift
            ;;
       *)
            # 只有在不是 --mode 的情况下才添加到 extra_args
            if [[ "$1" != --mode* ]]; then
                extra_args+=("$1")  
                echo "errorerror"              
            fi
            echo "extra_args: $1"
            shift
            ;;          
            
    esac    
done

echo "1"

# Check if directories exist
check_directories_and_files

echo "2"

# Call the function to set TEST_FILE and RESULT_FILE
set_test_and_result_files

echo "3"

# exec mysqltest
execute_mysqltest_with_files


# restore state
TEST_SET=""
SUITE=""
RECORD=0
ALL=0
NAMEMAXLEN=0

test_files=()
result_files=()
record_files=()


# echo "\"$MYSQLTEST_BIN\" --host=\"$HOST\" --port=\"$PORT\" --tmpdir=\"$TMPDIR\" --logdir=\"$LOGDIR\" --user=\"$USER\" --password=\"$PASSWORD\" --database=\"$DATABASE\" --timer-file=\"$TIMER_FILE\" --test-file=\"$TEST_FILE\" --result-file=\"$RESULT_FILE\"  \"$@\""



# Execute mysqltest with default parameters and additional parameters passed to the script
# "$MYSQLTEST_BIN" --host="$HOST" --port="$PORT" --tmpdir="$TMPDIR" --logdir="$LOGDIR" --user="$USER" --password="$PASSWORD" --database="$DATABASE" --timer-file="$TIMER_FILE" --test-file="$TEST_FILE" --result-file="$RESULT_FILE" "$@"

